package com.hanxiaozhang.system.service.impl;

import com.hanxiaozhang.constant.CacheName;
import com.hanxiaozhang.constant.DelFlagEnum;
import com.hanxiaozhang.result.ResultCode;
import com.hanxiaozhang.result.Result;
import com.hanxiaozhang.security.CurrentUserUtil;
import com.hanxiaozhang.system.dao.UserDeptDao;
import com.hanxiaozhang.system.dto.DeptDTO;
import com.hanxiaozhang.system.entity.UserDeptEntity;
import com.hanxiaozhang.util.BigDecimalUtil;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.hanxiaozhang.system.dao.DeptDao;
import com.hanxiaozhang.system.service.DeptService;
import org.springframework.transaction.annotation.Transactional;


/**
 * 部门表
 *
 * @author hanxiaozhang
 * @email hanxiaozhang2018@sina.com
 * @date 2021-03-21
 */
@Service
public class DeptServiceImpl implements DeptService {

    @Resource
    private DeptDao deptDao;
    @Resource
    private UserDeptDao userDeptDao;

    @Override
    public DeptDTO get(Long deptId) {
        return deptDao.get(deptId);
    }

    @Override
    public List<DeptDTO> list(Map<String, Object> map) {
        return deptDao.list(map);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = {CacheName.CURRENT_USER_BY_USER_ID_2HOUR}, allEntries = true)
    public int save(DeptDTO dept) {
        if (dept.getParentName().equals("无")) {
            dept.setParentId(0L);
        } else {
            deptDao.updateSubCountById(dept.getParentId(), 1);
        }
        dept.setSubCount(0)
                .setCreateBy(CurrentUserUtil.getUserName())
                .setCreateDate(LocalDateTime.now())
                .setDelFlag(DelFlagEnum.NORMAL.getCode());
        return deptDao.save(dept);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = {CacheName.CURRENT_USER_BY_USER_ID_2HOUR}, allEntries = true)
    public int update(DeptDTO dept) {

        dept.setUpdateBy(CurrentUserUtil.getUserName())
                .setUpdateDate(LocalDateTime.now());
        return deptDao.update(dept);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = {CacheName.CURRENT_USER_BY_USER_ID_2HOUR}, allEntries = true)
    public Result remove(Long deptId, Long parentId) {
        List<UserDeptEntity> list = userDeptDao.listByDeptId(deptId);
        if (!list.isEmpty()) {
            return Result.error(ResultCode.DATA_EXISTED_RELATION);
        }
        deptDao.updateSubCountById(parentId, -1);
        deptDao.remove(deptId);
        return Result.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = {CacheName.CURRENT_USER_BY_USER_ID_2HOUR}, allEntries = true)
    public Result batchRemove(Long[] deptIds, Long[] parentIds) {
        List<UserDeptEntity> list = userDeptDao.listByDeptIds(Arrays.asList(deptIds));
        if (!list.isEmpty()) {
            return Result.error(ResultCode.DATA_EXISTED_RELATION);
        }
        deptDao.batchRemove(deptIds);
        Map<Long, Long> idAndCountMap = Arrays.stream(parentIds).collect(Collectors.groupingBy((x -> x), Collectors.counting()));
        if (!idAndCountMap.isEmpty()) {
            idAndCountMap.forEach((id, count) -> {
                deptDao.updateSubCountById(id, (int) ((-1) * count));
            });
        }
        return Result.success();
    }

    public static void main(String[] args) {
        System.out.println(BigDecimalUtil.round(BigDecimalUtil.div(new BigDecimal(2), new BigDecimal(3)).multiply(new BigDecimal(100))));
        Long[] parentIds = {1L, 1L, 2L, 2L, 3L};
        Map<Long, Long> idAndCountMap = Arrays.stream(parentIds).collect(Collectors.groupingBy((x -> x), Collectors.counting()));
        idAndCountMap.forEach((id, count) -> {
            System.out.println("id: " + id + "count: " + count * (-1));
        });
    }

}
